"""
操作系统编辑对话框
"""

import logging
from typing import Dict, Any, Optional
from datetime import datetime, date
from PyQt5.QtWidgets import (
    QVBoxLayout, QHBoxLayout, QFormLayout, QLineEdit, QComboBox,
    QTextEdit, QGroupBox, QLabel, QGridLayout, QSpacerItem, 
    QSizePolicy, QWidget, QDateEdit
)
from PyQt5.QtCore import Qt, QDate
from PyQt5.QtGui import QIntValidator
from PyQt5.QtWidgets import QMessageBox

from src.app.ui.base_dialog import BaseDialog
from src.app.modules.os.service import OsService
from src.app.modules.os.utils import OsUtils
from src.app.modules.asset.service import AssetService

logger = logging.getLogger(__name__)

class OsDialog(BaseDialog):
    """操作系统编辑对话框"""
    
    def __init__(self, parent=None, os_data: Optional[Dict[str, Any]] = None):
        self.is_edit = os_data is not None
        self.os_data = os_data or {}
        
        # 在调用父类构造函数之前初始化服务
        self.service = OsService()
        self.utils = OsUtils()
        self.asset_service = AssetService()
        
        title = "编辑操作系统" if self.is_edit else "新增操作系统"
        super().__init__(parent, title=title, width=600, height=500)
        
        if self.is_edit:
            self.load_data()
    
    def create_content_widget(self):
        """创建内容区域"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # 基本信息组
        basic_group = self.create_basic_info_group()
        layout.addWidget(basic_group)
        
        # 安装信息组
        install_group = self.create_install_info_group()
        layout.addWidget(install_group)
        
        # 兼容性检查组
        compat_group = self.create_compatibility_group()
        layout.addWidget(compat_group)
        
        # 添加弹性空间
        layout.addStretch()
        
        return widget
    
    def create_basic_info_group(self):
        """创建基本信息组"""
        group = QGroupBox("基本信息")
        layout = QFormLayout(group)
        
        # 设备资产选择
        self.asset_combo = QComboBox()
        self.asset_combo.setMinimumWidth(300)
        layout.addRow("设备资产 *:", self.asset_combo)
        
        # 操作系统名称
        self.os_name_edit = QLineEdit()
        self.os_name_edit.setPlaceholderText("如：CentOS、Ubuntu、Windows Server")
        layout.addRow("操作系统名称 *:", self.os_name_edit)
        
        # 版本号
        self.version_edit = QLineEdit()
        self.version_edit.setPlaceholderText("如：7.6、20.04、2022")
        layout.addRow("版本号 *:", self.version_edit)
        
        # 加载设备资产列表
        self.load_assets()
        
        # 连接信号
        self.asset_combo.currentIndexChanged.connect(self.on_asset_changed)
        self.os_name_edit.textChanged.connect(self.on_os_name_changed)
        
        return group
    
    def create_install_info_group(self):
        """创建安装信息组"""
        group = QGroupBox("安装信息")
        layout = QFormLayout(group)
        
        # 安装目录
        self.install_dir_edit = QLineEdit()
        self.install_dir_edit.setPlaceholderText("如：/opt/centos 或 C:\\\\CentOS")
        layout.addRow("安装目录:", self.install_dir_edit)
        
        # 安装日期
        self.install_date_edit = QDateEdit()
        self.install_date_edit.setCalendarPopup(True)
        self.install_date_edit.setDate(QDate.currentDate())
        layout.addRow("安装日期:", self.install_date_edit)
        
        return group
    
    def create_compatibility_group(self):
        """创建兼容性检查组"""
        group = QGroupBox("兼容性检查")
        layout = QVBoxLayout(group)
        
        # 兼容性状态
        self.compat_label = QLabel("请选择设备资产和操作系统")
        self.compat_label.setStyleSheet("padding: 10px; background-color: #f5f5f5; border: 1px solid #ddd;")
        layout.addWidget(self.compat_label)
        
        # 推荐操作系统
        self.recommend_label = QLabel("推荐操作系统：")
        self.recommend_label.setWordWrap(True)
        self.recommend_label.setStyleSheet("padding: 10px; background-color: #e8f5e8; border: 1px solid #4CAF50;")
        layout.addWidget(self.recommend_label)
        
        return group
    
    def load_assets(self):
        """加载设备资产列表"""
        try:
            assets = self.asset_service.get_all_assets()
            
            self.asset_combo.clear()
            
            for asset in assets:
                display_text = f"{asset['asset_name']} ({asset['asset_type']})"
                self.asset_combo.addItem(display_text, asset['asset_id'])
                
        except Exception as e:
            logger.error(f"加载设备资产列表失败: {str(e)}")
    
    def load_data(self):
        """加载数据"""
        try:
            # 设置设备资产
            asset_id = self.os_data.get('asset_id')
            if asset_id:
                for i in range(self.asset_combo.count()):
                    if self.asset_combo.itemData(i) == asset_id:
                        self.asset_combo.setCurrentIndex(i)
                        break
            
            # 设置基本信息
            self.os_name_edit.setText(self.os_data.get('os_name', ''))
            self.version_edit.setText(self.os_data.get('version', ''))
            
            # 设置安装信息
            self.install_dir_edit.setText(self.os_data.get('install_dir', ''))
            
            install_date = self.os_data.get('install_date')
            if install_date:
                if isinstance(install_date, str):
                    try:
                        date_obj = datetime.strptime(install_date, '%Y-%m-%d').date()
                        self.install_date_edit.setDate(QDate(date_obj))
                    except ValueError:
                        pass
                elif isinstance(install_date, date):
                    self.install_date_edit.setDate(QDate(install_date))
            
            # 更新兼容性检查
            self.update_compatibility_check()
            
        except Exception as e:
            logger.error(f"加载数据失败: {str(e)}")
    
    def on_asset_changed(self):
        """设备资产变化事件"""
        self.update_compatibility_check()
    
    def on_os_name_changed(self):
        """操作系统名称变化事件"""
        self.update_compatibility_check()
    
    def update_compatibility_check(self):
        """更新兼容性检查"""
        try:
            asset_id = self.asset_combo.currentData()
            os_name = self.os_name_edit.text().strip()
            
            if not asset_id or not os_name:
                self.compat_label.setText("请选择设备资产和操作系统")
                self.compat_label.setStyleSheet("padding: 10px; background-color: #f5f5f5; border: 1px solid #ddd;")
                self.recommend_label.setText("推荐操作系统：")
                return
            
            # 获取设备资产信息
            assets = self.asset_service.get_asset_list()
            current_asset = None
            for asset in assets:
                if asset['asset_id'] == asset_id:
                    current_asset = asset
                    break
            
            if not current_asset:
                return
            
            # 检查兼容性
            is_compatible, message = self.utils.is_os_compatible_with_asset(
                os_name, current_asset['asset_type']
            )
            
            # 更新兼容性显示
            if is_compatible:
                compat_text = f"✅ {message}"
                
                # 检查特殊场景
                is_special, scenario_type = self.utils.is_special_scenario_os(os_name, current_asset['asset_type'])
                if is_special:
                    compat_text += f"\n📋 特殊场景：{scenario_type}"
                
                self.compat_label.setText(compat_text)
                self.compat_label.setStyleSheet("padding: 10px; background-color: #e8f5e8; border: 1px solid #4CAF50; color: #2e7d32;")
            else:
                self.compat_label.setText(f"❌ {message}")
                self.compat_label.setStyleSheet("padding: 10px; background-color: #ffebee; border: 1px solid #f44336; color: #c62828;")
            
            # 更新推荐操作系统
            recommendations = self.utils.get_os_recommendations(current_asset['asset_type'])
            if recommendations:
                rec_text = "推荐操作系统：\n" + "\n".join(f"• {rec}" for rec in recommendations[:5])
                self.recommend_label.setText(rec_text)
            else:
                self.recommend_label.setText("推荐操作系统：暂无推荐")
            
            # 特殊场景提示
            if current_asset['asset_type'] in ['安全设备', 'SECURITY_DEVICE']:
                self.compat_label.setText(self.compat_label.text() + "\n⚠️ 注意：安全设备通常直接关联业务系统")
                
        except Exception as e:
            logger.error(f"更新兼容性检查失败: {str(e)}")
    
    def get_data(self) -> Dict[str, Any]:
        """获取表单数据"""
        data = {
            'asset_id': self.asset_combo.currentData(),
            'os_name': self.os_name_edit.text().strip(),
            'version': self.version_edit.text().strip(),
            'install_dir': self.install_dir_edit.text().strip() or None,
            'install_date': self.install_date_edit.date().toString('yyyy-MM-dd') or None
        }
        
        if self.is_edit:
            data['os_id'] = self.os_data.get('os_id')
        
        return data
    
    def validate_data(self) -> tuple[bool, str]:
        """验证表单数据"""
        data = self.get_data()
        
        # 使用工具类验证
        is_valid, error_msg = self.utils.validate_os_data(data, self.is_edit)
        if not is_valid:
            return False, error_msg
        
        # 额外的业务逻辑验证
        if not data['asset_id']:
            return False, "请选择设备资产"
        
        # 验证安装目录格式
        if data['install_dir']:
            asset_id = data['asset_id']
            assets = self.asset_service.get_asset_list()
            current_asset = None
            for asset in assets:
                if asset['asset_id'] == asset_id:
                    current_asset = asset
                    break
            
            if current_asset:
                os_type = self.utils.get_os_type(data['os_name'])
                is_valid, error_msg = self.utils.validate_install_directory(
                    data['install_dir'], os_type
                )
                if not is_valid:
                    return False, error_msg
        
        return True, ""
    
    def accept(self):
        """确定按钮点击事件"""
        try:
            # 验证数据
            is_valid, error_msg = self.validate_data()
            if not is_valid:
                QMessageBox.warning(self, "验证失败", error_msg)
                return
            
            # 获取数据
            data = self.get_data()
            
            # 保存数据
            if self.is_edit:
                result = self.service.update_os(data['os_id'], data)
            else:
                result = self.service.create_os(data)
            
            if result['success']:
                super().accept()
            else:
                QMessageBox.warning(self, "保存失败", result['message'])
                
        except Exception as e:
            logger.error(f"保存操作系统失败: {str(e)}")
            QMessageBox.critical(self, "错误", f"保存操作系统失败: {str(e)}")